export const types = {
  FUNCTION: 'func', // 功能性
  VALUE: 'value', // 值转化
};

export default class Directive {
  directs = [];
  refs = [];

  constructor(key = '', scope) {
    const regExp = /:\((.*?)\)/g;
    const keys = key.split(':');
    // ie和firefox不支持向后断言 /(?<=:\().*?(?=\))/g
    const dirs = (key.match(regExp) || []).map(dir => dir.replace(regExp, '$1'));
    
    this.realKey = keys[0];
    this.scope = scope;

    this.register(dirs);
  }

  register(dirs) {
    // number={default: 1, max: 10}
    this.directs = dirs.map(dir => {
      const result = dir.split('=');
      const dirName = result[0];
      const dirParams = result[1];

      try {
        const TheDirective = require(`./${dirName}`).default;
        const params = this.parse(dirParams);

        return new TheDirective(params);
      } catch(e) {
        console.log(`Fail to init directive ${dirName}`);
        return '';
      }
    });
  }

  with(value, handle) {
    if (!this.directs.length) {
      return handle(value);
    }

    // 优先执行值转化的dir
    this.directs.filter(d => types.VALUE === d.type)
      .forEach(dir => {
        value = dir.with(value);
      });

    value = handle(value);

    this.directs.filter(d => types.FUNCTION === d.type)
      .forEach(dir => {
        this[dir.name] = dir.with(value);
      });

    return value;
  }

  parse(params = "{}") {
    try {
      params = params.replace(/'/g, "\\'");

      return new Function(`
        with(this) {
          return eval('(${params})')
        }
      `).call(this.scope);
    } catch(e) {
      console.log(`parse Error: ${params}`);
      return {};
    }
  }
}